package com.wangdong.mijiqiqi.handler;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;

import java.lang.ref.WeakReference;

/**
 * 作者：wangdong on 2018/9/11 15:48
 * 邮箱：2100520956@qq.com
 *
 * 开发中编写Handler类时，ADT时常提示加上“@SuppressLint("HandlerLeak")”的标记，意味着这里可能发生内存泄漏。
 * 因为Handler类总是处理异步任务，每当它postDelayed一个任务时，依据postDelayed的间隔都得等待一段时间，倘若页面在这期间退出，
 * 就导致异步任务Runnable持有的引用无法回收，Runnable通常持有Activity的引用，造成Activity都无法回收了。


 上面描述可能不好理解，确实也不容易解释清楚，那还是直接跳过繁琐的概念，讲讲如何解决HandlerLeak的问题。下面是预防此类内存泄漏的三个方法：

 1、如果异步任务是由Handler对象的postDelayed方法发起，那么可用对应的removeCallbacks方法回收之，把消息对象从消息队列移除就行了。
 但若线程是由start方法启动，则不适合使用该方法，但我们可尽量避免start方式启动。

 2、按Android官方的推荐做法，可把Handler类改为静态类(static)，同时Handler内部使用WeakReference关键字来持有目标的引用。
 之所以使用静态类，是因为静态类不持有目标的引用，不会影响自动回收机制。但是不持有目标的引用，
 Handler内部也就无法操作Activity上面的控件（因为不持有Activity的引用）。为解决该问题，在构造Handler类时就得初始化目标的弱引用，
 弱引用不同于前面的引用（强引用），弱引用相当于一个指针，指针指向的地址随时可以回收，这又带来一个新问题，就是弱引用指向的对象可能是空的。
 幸好这个问题好解决，Handler内部使用目标前先判断以下弱引用是否为空就行了。

 3、把Handler对象作为APP的全局变量，比如把Handler对象放入Application的声明中，这样只要app在运行，Handler对象一直都存在。
 既然避免了为Handler分配内存，也就间接避免了内存泄漏。Application的介绍参见《Android开发笔记（二十八）利用Application实现内存读写》。
 */

public class HandlerActivity extends Activity
{


    private int mType;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        Bundle bundle = getIntent().getExtras();
        mType = bundle.getInt("type");

    }

    @Override
    protected void onStart() {
         if (mType == 1) {  //引用有释放
            mHandler.postDelayed(mRefresh, 10000);
        } else if (mType == 2) {  //静态弱引用
            mMyHandler.postDelayed(mRunnableRefresh, 10000);
        } else if (mType == 3) {  //线程弱引用
            mMyHandler.postDelayed(mThreadRefresh, 10000);
        }
        super.onStart();
    }
    private Handler mHandler = new Handler();
    private Runnable mRefresh = new Runnable() {
        @Override
        public void run() {


        }
    };

    @Override
    protected void onStop() {
        if (mType == 1) {
            mHandler.removeCallbacks(mRefresh);
        }
        super.onStop();
    }




    private Handler mMyHandler = new MyHandler(this);

    private static class MyHandler extends Handler {
        public static WeakReference<HandlerActivity> mActivity;

        public MyHandler(HandlerActivity activity) {
            mActivity = new WeakReference<HandlerActivity>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            HandlerActivity act = mActivity.get();

        }
    }



    private static Runnable mRunnableRefresh = new Runnable() {
        @Override
        public void run() {
            HandlerActivity act = MyHandler.mActivity.get();
            if (act != null) {
                act.mMyHandler.sendEmptyMessage(0);
            }
        }
    };




    private static Thread mThreadRefresh = new Thread() {
        @Override
        public void run() {
            HandlerActivity act = MyHandler.mActivity.get();
            if (act != null) {
                act.mMyHandler.sendEmptyMessage(0);
            }
        }
    };

}
